#ifndef XG_HTTPHELPER_CPP
#define XG_HTTPHELPER_CPP
//////////////////////////////////////////////////////////
#include "../HttpHelper.h"
#include "../../openssl/SSLSocket.h"

static thread_local int status = 0;

int HttpHelper::GetLastStatus()
{
	return status;
}
void HttpHelper::SetLastStatus(int code)
{
	status = code;
}
sp<Socket> HttpHelper::Connect(const string& ip, int port, bool crypted)
{
	return crypted ? SSLSocketPool::Connect(ip, port) : SocketPool::Connect(ip, port);
}
int HttpHelper::GetLinkSet(set<string>& uset, const string& html, const string& host)
{
	string str = html;
	string hdr = "https";
	string key = stdx::trim(host, HTTP_SPACELIST);
	const char* taglist[] = {"http://", "https://", "href=", "src=", "url("};

	if (key.find(hdr) == 0)
	{
		hdr += ":";
	}
	else
	{
		hdr[4] = ':';
	}

	stdx::tolower(str);

	for (int i = 0; i < ARR_LEN(taglist); i++)
	{
		string url;
		auto tag = taglist[i];
		auto cnt = strlen(tag);
		auto pos = str.find(tag, 0);
		size_t a, b, c, d, e, f, g, m, n;

		while (pos != string::npos && pos < str.length())
		{
			if (i > 1) pos += cnt;

			a = str.find('\'', pos + 4); if (a == string::npos) a = 0xFFFFFFF;
			b = str.find('\"', pos + 4); if (b == string::npos) b = 0xFFFFFFF;
			c = str.find('>', pos + 4); if (c == string::npos) c = 0xFFFFFFF;
			d = str.find('<', pos + 4); if (d == string::npos) d = 0xFFFFFFF;
			e = str.find(')', pos + 4); if (e == string::npos) e = 0xFFFFFFF;
			f = str.find(';', pos + 4); if (f == string::npos) f = 0xFFFFFFF;
			g = str.find(' ', pos + 4); if (g == string::npos) g = 0xFFFFFFF;
			m = str.find('\r', pos + 4); if (m == string::npos) m = 0xFFFFFFF;
			n = str.find('\n', pos + 4); if (n == string::npos) n = 0xFFFFFFF;

			for (auto item : {a, b, c, d, f, g, m, n})
			{
				if (e > item) e = item;
			}

			if (e < 0xFFFFFFF)
			{
				url = html.substr(pos, e - pos);
				pos = str.find(tag, e + 1);

				if ((url = stdx::trim(url, " \r\n\t(;)\'\"")).length() > 1)
				{
					if (key.length() > 0 && url.find("http") && url.find("www"))
					{
						if (url[0] == '/')
						{
							url = url[1] == '/' ? hdr + url : host + url;
						}
						else
						{
							url = key + "/" + url;
						}
					}

					uset.insert(url);
				}
			}
			else
			{
				pos = str.find(tag, pos + 1);
			}
		}
	}

	return uset.size();
}
string HttpHelper::GetLink(const string& path, const string& host, int port, bool crypted)
{
	if (crypted)
	{
		if (port == 443)
		{
			return stdx::format("https://%s/%s", host.c_str(), path.c_str());
		}
		else
		{
			return stdx::format("https://%s:%d/%s", host.c_str(), port, path.c_str());
		}
	}
	else
	{
		if (port == 80)
		{
			return stdx::format("http://%s/%s", host.c_str(), path.c_str());
		}
		else
		{
			return stdx::format("http://%s:%d/%s", host.c_str(), port, path.c_str());
		}
	}
}
SmartBuffer HttpHelper::GetResultEx(const string& url, const string& data, const string& contype, const string& cookie, bool tiny)
{
	string link = url;

	for (int i = 0; i < 3; i++)
	{
		int port;
		string ip;
		string host;
		string path;
		bool crypted;
		HttpRequest request;

		if (!HttpRequest::GetInfoFromURL(link, host, path, ip, port, crypted))
		{
			status = XG_SENDFAIL;

            return SmartBuffer();
		}

		request.init(path, tiny);

		if (data.length() > 0)
		{
			request.setMethod(ePOST);
			request.setDataString(data);
		}

		request.setHeadHost(host, port);

		if (contype.length() > 0) request.setContentType(contype);

		if (cookie.length() > 0) request.setHeadValue("Cookie", cookie);

        sp<Socket> sock = Connect(ip, port, crypted);

		if (!sock)
		{
			status = XG_SENDFAIL;

			return SmartBuffer();
		}

        sp<HttpResponse> response = request.getResponse(sock);

        if (!response)
        {
			status = XG_RECVFAIL;

            return SmartBuffer();
        }

		status = response->getErrorCode();

		if (status == 200) return response->getResult();

		link = response->getHeadValue("Location");

		if (link.empty())
		{
			link = response->getHeadValue("location");
				
			if (link.empty()) return response->getResult();
		}
	}

	status = XG_DATAERR;

	return SmartBuffer();
}
//////////////////////////////////////////////////////////
#endif